package com.zkr.planclass.service;


import com.zkr.planclass.enummodel.StatusEnum;
import com.zkr.planclass.mapper.PlanClassMapper;
import com.zkr.planclass.model.*;
import com.zkr.util.*;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by lenovo on 2020/12/11.
 */
@Service
public class PlanClassServiceImpl implements PlanClassService {
    @Autowired
    private PlanClassMapper planClassMapper;

    @Override
    public ResultVo queryPage(PlanClassSelectVo planClassSelectVo) {
        int count = planClassMapper.queryCount(planClassSelectVo);
        List<PlanClassVo> planClassVoList = planClassMapper.queryPage(planClassSelectVo);
        for (PlanClassVo planClassVo : planClassVoList) {
           /* if (planClassVo.getStatus() == true) {
                planClassVo.setStatusName("启用");
            } else if (planClassVo.getStatus() == false) {
                planClassVo.setStatusName("禁用");
            }*/
           Integer status = planClassVo.getStatus()==true?1:0;
           for (StatusEnum c:StatusEnum.values()) {
            if (c.getValue().equals(planClassVo.getStatus())){
                planClassVo.setStatusName(c.getName());
            }
           }

        }
        AllRecords allRecords = new AllRecords();
        allRecords.setPageIndex(planClassSelectVo.getPageIndex());
        allRecords.setDataList(planClassVoList);
        allRecords.setPageSize(planClassSelectVo.getPageSize());
        allRecords.setTotalNumber(count);
        allRecords.resetTotalNumber(count);
        return ResultBuilderVo.success(allRecords);

    }

    @Override
    @Transactional
    public ResultVo add(@Valid List<PlanClassAddVo> planClassAddVoList) {
        List<String> codeList = new ArrayList<>();
        for (PlanClassAddVo planClassAddVo:planClassAddVoList){
            codeList.add(planClassAddVo.getCode());
        }
        List<String> queryCodes = planClassMapper.queryByCodes(codeList);
        if (queryCodes.size()>0){
            return ResultBuilderVo.error("已经存在编码为"+queryCodes);
        }
        Date newDate = new Date();

        /*//验证是否已经存在编码或名称
        PlanClassVo planClassVoName = planClassMapper.queryByName(planClassAddVo.getName());
        if (planClassVoName !=null){
            return ResultBuilderVo.error("备件计划大类名称已经存在");
        }
        PlanClassVo planClassVoCode = planClassMapper.queryByCode(planClassAddVo.getCode());
        if(planClassVoCode != null){
            return ResultBuilderVo.error("备件计划大类编码已经存在");
        }*/
        for (PlanClassAddVo planClassAddVo:planClassAddVoList){
            planClassAddVo.setCreateName("李四");
            planClassAddVo.setCreateTime(new Date());
            planClassAddVo.setUpdateName("李四");
            planClassAddVo.setUpdateTime(new Date());
        }


        planClassMapper.adds(planClassAddVoList);
        return ResultBuilderVo.success();


    }

    @Override
    public ResultVo exportFile(PlanClassSelectVo planClassSelectVo, HttpServletResponse response) throws Exception {
        //查询数据
        List<PlanClassVo> planClassVoList = planClassMapper.queryExportData(planClassSelectVo);
        for(PlanClassVo planClassVo:planClassVoList){
            Integer status = planClassVo.getStatus()==true?1:0;
            planClassVo.setStatusName(StatusEnum.getName(status));
        }
        if (planClassVoList.size()>5000){
            return ResultBuilderVo.error("当前数据条数为"+planClassVoList.size()+",数据大于5000条，请重新选择条件，数据小于5000条才能导出！");
        }
        //获取响应输出流
        ServletOutputStream out = response.getOutputStream();
        //给输出文件设置名称
        POIClass.toPackageOs(response, "计划大类导出模板");
        //读取模板中的数据
        InputStream in = ExportUtil.toPackageIn("static/计划大类导出.xlsx");
        //根据模板的数据、把查询出来的数据给摸版SHeet1组中的数据赋值、把excel输出到浏览器上
        writeDataToExcel(in, "Sheet1", planClassVoList, out);
        if (in != null) {
            in.close();
            out.close();
        }
        return null;
    }

    // 由于此方法不能通用, 所以单独写在这里
    private void writeDataToExcel(InputStream in, String sheetName,
                                  List<PlanClassVo> resultList, ServletOutputStream out) throws Exception {
        //POi读取模板
        XSSFWorkbook wb = new XSSFWorkbook(in);
        //读取sheet1中的数据
        Sheet sheet = wb.getSheet(sheetName);
        if (sheet != null) {
            //向sheet1中赋值，设置样式
            toResultListValueInfo(sheet, resultList);
        }
        //把数据写入到输出流中
        wb.write(out);
        //关闭poi方法
        wb.close();
    }

    /**
     * 插入excel表中项目信息
     *
     * @param sheet
     */
    private void toResultListValueInfo(Sheet sheet, List<PlanClassVo> plantList) {
        //从第4行开始赋值
        int row_column = 5;
        int xuhao =1;
        //遍历数据集合
        for (PlanClassVo obj : plantList) {
            //创建一行的方法
            Row row = sheet.createRow(row_column);
            // 给第一列序号赋值赋值
            POIClass.toCellValue(row,0, xuhao + "");
            // 给第二列编码赋值
            POIClass.toCellValue(row, 1, obj.getCode() + "");
            // 给第3列名称赋值
            POIClass.toCellValue(row, 2, obj.getName() + "");
            // 给状态赋值
            POIClass.toCellValue(row, 3, obj.getStatusName() + "");
            //给描述赋值
            POIClass.toCellValue(row, 4, obj.getRemark() + "");
            row_column++;
            xuhao++;
        }
    }


    @Override
    @Transactional
    public ResultVo update(@Valid PlanClassUpdateVo planClassUpdateVo) {
        //修改时1.名称不能重复
        //2.只有禁用状态才能修改数据
        //3.修改数据库
       PlanClassVo planClassVoName = planClassMapper.queryByName(planClassUpdateVo.getName());
        /*if(planClassVoName != null){
            return ResultBuilderVo.error("备件名称已经存在");
        }*/
        if (planClassVoName != null){
            if (!planClassVoName.getId().equals(planClassUpdateVo.getId())){
                return ResultBuilderVo.error("备件名称已经存在");
            }

        }
        /*LegalPlantClassVo planClassVo = planClassMapper.queryById(planClassUpdateVo.getId());
        if (planClassVo.getStatus() == true){
            return ResultBuilderVo.error("修改时必须为禁用状态");
        }*/
        PlanClassVo planClassVo1  = new PlanClassVo();
        BeanUtils.copyProperties(planClassUpdateVo,planClassVo1);
        planClassVo1.setUpdateTime(new Date());
        planClassVo1.setUpdateName("李四");
        planClassMapper.update(planClassVo1);
        return ResultBuilderVo.success();

    }

    @Override
    @Transactional
    public ResultVo updateStatus(@Valid PlanClassUpdateStatusVo planClassUpdateStatusVo) {

       /* LegalPlantClassVo planClassVo = planClassMapper.queryById(planClassUpdateStatusVo.getId());
        if (planClassVo==null){
            return ResultBuilderVo.error("修改数据不存在!");
        }*/
        PlanClassVo planClassVo1 = new PlanClassVo();
        BeanUtils.copyProperties(planClassUpdateStatusVo,planClassVo1);
        planClassVo1.setUpdateTime(new Date());
        planClassVo1.setUpdateName("李四");
        planClassMapper.updateStatus(planClassVo1);
        return ResultBuilderVo.success();

    }

    @Override
    public ResultVo importFile(MultipartFile file) throws Exception{
        //poi导入
        //1.判断是否为空
        //2.判断版本
        //3.使用POI读取到文件的内容
        //4.把文件中的内容解析,放入到list对象中
        //5.进行各种验证  1.验证是否为空  2.验证长度是否合法  3.状态数值转换
           // 4.名称.编码验证是否重复  5.状态是否合法  6.名称.编码是否存在
        //6.批量入库


        //判断是否为空
        if(file==null){
            return ResultBuilderVo.error("导入文件不能为空!");
        }
        //判断版本
        if (!file.getOriginalFilename().contains(".xlsx")){
            return ResultBuilderVo.error("请导入以.xlsx结尾的表格!");
        }

        ResultVo<List<PlanClassAddVo>> resultVo = poiImport(file);
        if (!resultVo.getSuccess()){
            return resultVo;
        }


        //验证长度.是否为空 状态数值转换
        ResultVo<List<PlanClassAddVo>> validate = validate(resultVo.getData());
        if (!validate.getSuccess()){
            return validate;
        }
        //名称 编码验证是否重复 名称 编码是否有存在
        ResultVo resultVo1 = validateRepeat(validate.getData());
        if (!resultVo1.getSuccess()){
            return resultVo1;
        }



         //6.批量入库
        ResultVo add = add(validate.getData());
        if (!add.getSuccess()){
            return add;
        }
        return  ResultBuilderVo.success();
    }



    public ResultVo validateRepeat (List<PlanClassAddVo> planClassVoList){
        //名称 编码验证是否重复
        //存放有可能重复的code信息
        List<String> codeList  = new ArrayList<>();
        for (PlanClassAddVo planClassVo:planClassVoList){
            codeList.add(planClassVo.getCode());
        }
        List<String> codeAll = new ArrayList<>();
        List<String> repeatCode = new ArrayList<>();

        for (String code:codeList){
            if (codeAll.contains(code)){
                repeatCode.add(code);
            }else {
                codeAll.add(code);
            }
        }
        if (repeatCode.size()>0){
            return  ResultBuilderVo.error("存在重复数据,重复数据为"+repeatCode);
        }
        return ResultBuilderVo.success();
    }

    public ResultVo validate(List<PlanClassAddVo> planClassVoList){


        if (CollectionUtils.isEmpty(planClassVoList)){
            return ResultBuilderVo.error("请检查数据,导入的数据不能为空!");
        }
        for (PlanClassAddVo planClassAddVo:planClassVoList){
            if (StringUtils.isEmpty(planClassAddVo.getCode())){
                return ResultBuilderVo.error("编码不能为空!");
            }else {
                if (planClassAddVo.getCode().length()>100){
                    return ResultBuilderVo.error("编码长度过长!");
                }
            }
            if (StringUtils.isEmpty(planClassAddVo.getName())){
                return ResultBuilderVo.error("名称不能为空!");
            }else {
                if (planClassAddVo.getName().length()>100){
                    return ResultBuilderVo.error("名称长度过长!");
                }
            }
            if (StringUtils.isEmpty(planClassAddVo.getStatusName())){
                return ResultBuilderVo.error("状态不能为空!");
            }else {
                Integer value = StatusEnum.getValue(planClassAddVo.getStatusName());
                if (value==null){
                    return ResultBuilderVo.error("状态输入错误,只允许填写启用或者禁用");
                }else {
                    Boolean status = value==1?true:false;
                    planClassAddVo.setStatus(status);
                }
            }
        }
        return ResultBuilderVo.success(planClassVoList);
    }

    //poi读取信息
    public ResultVo poiImport(MultipartFile file)throws Exception{
        //        3.模板是否是需要导入的模板，验证模板是否正确
        XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());
        //获取单元格中的信息 at0是获取sheet1中的数据。
        XSSFSheet sheet = workbook.getSheetAt(0);
        System.out.println(sheet.getRow(sheet.getFirstRowNum()).getCell(0));
        //验证第一列第一行的表格标头信息是否为 “询价单导入”，如果不是，提示模板错误。
        if (!String.valueOf(sheet.getRow(sheet.getFirstRowNum()).getCell(0)).equals("计划大类导入模板")) {
            return ResultBuilderVo.error("模板错误，请检查模板！");
        }
        List<PlanClassVo> planClassVoList = new ArrayList<>();
        //遍历excel表格中的所有数据，从第五行开始读取，没有数据时终止遍历。
        for (int i = sheet.getFirstRowNum() + 4; i <= sheet.getLastRowNum(); i++) {
            //读取每一行的数据
            XSSFRow xssfRow = sheet.getRow(i);
            if(xssfRow!=null) {
                String test1 = String.valueOf(xssfRow.getCell(1)).trim();
                String test2 = String.valueOf(xssfRow.getCell(2)).trim();
                String test3 = String.valueOf(xssfRow.getCell(3)).trim();
                if (!test1.equals("")&&!test1.equals("null")
                        ||!test2.equals("")&&!test2.equals("null")
                        ||!test3.equals("")&&!test3.equals("null")){
                    //把每一行的数据放入到实体类中
                    ResultVo<PlanClassVo> inquiryImportVo = build(xssfRow);
                    if (!inquiryImportVo.getSuccess()){
                        return inquiryImportVo;
                    }
                    //把实体类中的数据放入到list集合中
                    planClassVoList.add(inquiryImportVo.getData());
                }

            }
        }
        return ResultBuilderVo.success(planClassVoList);
    }

    public ResultVo build(XSSFRow xssfRow){
        PlanClassAddVo planClassAddVo = new PlanClassAddVo();
        //4.格式问题，必须保持统一格式，统一为字符串格式导入
        planClassAddVo.setCode(String.valueOf(xssfRow.getCell(1)));
        planClassAddVo.setName(String.valueOf(xssfRow.getCell(2)));
        planClassAddVo.setStatusName(String.valueOf(xssfRow.getCell(3)));
        planClassAddVo.setRemark(String.valueOf(xssfRow.getCell(4)));
        return ResultBuilderVo.success(planClassAddVo);
    }
}


